package cn.ant.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;


/**
 * 关于Hello World模块的RabbitMQ配置信息
 * 一定需要加@SpringBootConfiguration注解，标注当前为配置类，交由Spring管理。
 *
 * @author Anhui AntLaddie <a href="https://juejin.cn/user/4092805620185316">(掘金蚂蚁小哥)</a>
 * @version 1.0
 **/
@SpringBootConfiguration
public class RabbitMQConfig {

    // 定义1：简单的直接交换机名称；定义2：简单队列名称；定义3：路由key
    public static final String SIMPLE_DIRECT_EXCHANGE = "simpleDirectExchange";
    public static final String SIMPLE_QUEUE_NAME = "simpleQueueName";
    public static final String SIMPLE_KEY = "simpleKey";

    /***
     * 创建交换机信息；
     * 注：Bean注解内不写名称，则Bean名称默认就是方法名
     * @return Exchange
     */
    @Bean(value = "simpleDirectExchange")
    public Exchange createSimpleDirectExchange() {
        // 这个ExchangeBuilder就是我们当初使用的如下方式一样：
        // channel.exchangeDeclare("交换机名称", "交换机类型",true, false, false, null);
        return ExchangeBuilder
                // 设置交换机类型（方法名已指定出交换机类型了）+交换机名称
                .directExchange(SIMPLE_DIRECT_EXCHANGE)
                // 设置交换机持久化
                .durable(true)
                // 设置交换机自动删除
                // .autoDelete()
                // 是否为内部交换机（true时，不能被生产者直接发送消息，只能由其他交换机发送）
                // .internal()
                // 额外参数（如alternate-exchange设置备用交换机）
                // .withArguments(new HashMap<>())
                // 构建
                .build();
    }

    /***
     * 创建队列信息；
     * 注：Bean注解内不写名称，则Bean名称默认就是方法名
     * @return Exchange
     */
    @Bean(value = "simpleQueueName")
    public Queue createSimpleQueueName() {
        // 这个QueueBuilder创建方式就是我们当初使用的如下方式一样：
        // 这下面注释的原生写法和下面的一样
        //      Map<String, Object> args = new HashMap<>();
        //      args.put("x-message-ttl", 30000);   // 消息存活时间 30 秒
        //      args.put("x-max-length", 100);      // 限制队列最大长度 100 条
        //      args.put("x-dead-letter-exchange", "exchangeName");  // 指定死信交换机
        //      args.put("x-dead-letter-routing-key", "dlxKey");  // 指定死信队列的路由键
        //      //对应参数意思：队列名称，持久化，排他队列，自动删除，额外参数
        //      channel.queueDeclare(SIMPLE_QUEUE_NAME,true,true,true,args)
        // 和上面原生方式一样的
        // return QueueBuilder.durable(SIMPLE_QUEUE_NAME)
        //         .autoDelete().ttl(30000).maxLength(100)
        //         .deadLetterExchange("exchangeName")
        //         .deadLetterRoutingKey("dlxKey")
        //         .withArguments(new HashMap<>()).exclusive().build();
        // 下面创建一个简单的消息队列了
        return QueueBuilder.durable(SIMPLE_QUEUE_NAME).build();
        // 说明：QueueBuilder.nonDurable("xxx") 是非持久化的队列
    }

    /***
     * 将队列信息绑定到交换机上
     * @param simpleDirectExchange 简单的直接交换机
     * @param simpleQueueName 简单的队列
     * @return Binding
     */
    @Bean(value = "simpleQueueBindSimpleExchange")
    public Binding createSimpleQueueBindSimpleExchange(
            @Qualifier(value = "simpleDirectExchange") Exchange simpleDirectExchange,
            @Qualifier(value = "simpleQueueName") Queue simpleQueueName) {
        // 这个BindingBuilder就是我们当初使用的如下方式一样：
        // channel.queueBind("队列名称", "交换机名称", "路由key");
        return BindingBuilder
                .bind(simpleQueueName).to(simpleDirectExchange).with(SIMPLE_KEY).noargs();
    }
}
